<template>
  <div class="vueFormBox">
    <el-form
      :class="formClass"
      :style="formStyle"
      :label-position="labelPosition"
      :show-message="showMessage"
      :model="formVal"
      :rules="formRules"
      :size="size"
      :hide-required-asterisk="hideRequiredAsterisk"
      :inline-message="inlineMessage"
      @submit.native.prevent
      :ref="formRef"
    >
      <el-row class="non-virtual-list" :gutter="gutter" wtag="el-row">
        <el-col
          :key="item.code || index"
          :pull="item.pull || 0"
          :push="item.push || 0"
          :span="item.span || span"
          :offset="item.offset"
          v-for="(item, index) in formData"
        >
          <el-form-item
            :label="item.title"
            :label-width="loadFormLabelWidth(item.labelWidth)"
            :prop="item.code"
            v-if="item.code && item.isVisiable"
          >
            <!--span文字-->
            <div style="line-height: 36px" v-if="item.type === 'span'">
              <span v-html="formVal[item.code]"></span>
            </div>
            <!--autoComplete输入补全建议框-->
            <my-autoComplete
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myAutocomplete_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'autoComplete'"
            ></my-autoComplete>
            <!--button按钮-->
            <my-button
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myButton_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :config="item.config"
              :formConfigData="formConfigData"
              v-else-if="item.type === 'button'"
            ></my-button>
            <!--checkbox多选框-->
            <my-checkbox
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myCheckbox_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'checkbox'"
            ></my-checkbox>
            <!--checkbox多选框按钮样式-->
            <my-checkbox-button
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myCheckboxBtn_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'checkboxBtn'"
            ></my-checkbox-button>
            <!--datepicker日期选择框-->
            <my-datePicker
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myDatepicker_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'datePicker'"
            ></my-datePicker>
            <my-dialogTree
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myTree_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'selectDialogTree'"
            >
            </my-dialogTree>
            <!--编辑器-->
            <my-editor
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myEditor_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :isContenteditable="!item.isDisabled"
              v-else-if="item.type === 'editor'"
            ></my-editor>
            <!--icon图标-->
            <my-icon
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myIcon_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              v-else-if="item.type === 'icon'"
            ></my-icon>
            <!--大文本、数字、input输入框-->
            <my-input
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myInput_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'input'"
            ></my-input>
            <!--inputNumber计数器-->
            <my-input-number
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myInputNumber_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'counter'"
            ></my-input-number>
            <!--quarterDatepicker季度日期框-->
            <my-quarterDatepicker
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myDatepicker_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'quarterDatepicker'"
            ></my-quarterDatepicker>
            <!--radio框-->
            <my-radio
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myRadio_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'radio'"
            ></my-radio>
            <my-radio-button
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myRadio_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'radioBtn'"
            ></my-radio-button>
            <!--select下拉框-->
            <my-select
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'mySelect_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'select'"
            ></my-select>
            <!--Switch 开关-->
            <my-switch
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'mySwitch_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'switch'"
            ></my-switch>
            <!--mytree弹框树结构-->
            <my-tree-model
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myTreeModel_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              :showName.sync="formVal[item.code + 'Name']"
              v-else-if="item.type === 'treeModel'"
            ></my-tree-model>
            <!--upload上传插件-->
            <my-upload
              v-bind="$attrs"
              v-on="$listeners"
              :ref="'myUpload_' + item.code + '_' + which"
              :which="which"
              :fromSource="item.fromSource"
              :modelKey="item.code"
              :model.sync="formVal[item.code]"
              :config="item.config"
              :formConfigData="formConfigData"
              :disabled="item.isDisabled"
              v-else-if="item.type === 'upload'"
            ></my-upload>
            <!--自定义插槽-->
            <slot :name="item.code" v-else-if="item.type === 'slot'"></slot>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </div>
</template>

<script>
import myAutoComplete from "@/components/vueForm/myAutoComplete.vue";
import myButton from "@/components/vueForm/myButton.vue";
import myCheckbox from "@/components/vueForm/myCheckbox.vue";
import myCheckboxButton from "@/components/vueForm/myCheckboxButton.vue";
import myDatePicker from "@/components/vueForm/myDatePicker.vue";
import myDialogTree from "@/components/vueForm/myDialogTree.vue";
import myEditor from "@/components/vueForm/myEditor.vue";
import myIcon from "@/components/vueForm/myIcon.vue";
import myInput from "@/components/vueForm/myInput.vue";
import myInputNumber from "@/components/vueForm/myInputNumber.vue";
import myQuarterDatepicker from "@/components/vueForm/myQuarterDatepicker.vue";
import myRadio from "@/components/vueForm/myRadio.vue";
import myRadioButton from "@/components/vueForm/myRadioButton.vue";
import mySelect from "@/components/vueForm/mySelect.vue";
import mySelectTree from "@/components/vueForm/mySelectTree.vue";
import mySwitch from "@/components/vueForm/mySwitch.vue";
import myTreeModel from "@/components/vueForm/myTreeModel.vue";
import myUpload from "@/components/vueForm/myUpload.vue";
import { getFormData } from "@/components/api/form.js";
import * as formAdapter from "@/components/vueForm/js/formAdapter.js";
import XEUtils from "xe-utils";
export default {
  name: "forms",
  components: {
    myAutoComplete,
    myButton,
    myCheckbox,
    myCheckboxButton,
    myDatePicker,
    myDialogTree,
    myEditor,
    myIcon,
    myInput,
    myInputNumber,
    myQuarterDatepicker,
    myRadio,
    myRadioButton,
    mySelect,
    mySelectTree,
    mySwitch,
    myTreeModel,
    myUpload,
  },
  props: {
    //自定义ref
    formRef: {
      type: [Number, String],
      default() {
        return "forms";
      },
    },
    // form自定义的样式
    formStyle: {
      type: [String, Object],
      default() {
        return "";
      },
    },
    // 当前表单外部样式
    formClass: {
      type: [String, Object],
      default() {
        return "";
      },
    },
    // 是否显示校验错误信息
    showMessage: {
      type: Boolean,
      default() {
        return true;
      },
    },
    inlineMessage: {
      //是否以行内形式展示校验信息
      type: Boolean,
      default() {
        return true;
      },
    },
    //表单项排列位置
    labelPosition: {
      type: [String, Object],
      default() {
        return "right";
      },
    },
    hideRequiredAsterisk: {
      //是否显示必填字段的标签旁边的红色星号
      type: Boolean,
      default() {
        return true;
      },
    },
    // 用于控制该表单内组件的尺寸medium / small / mini
    size: {
      type: String,
      default() {
        return "medium";
      },
    },
    // 栅格栏的分配
    span: {
      type: Number,
      default() {
        return 24;
      },
    },
    // 栅格栏之间的间隔
    gutter: {
      type: Number,
      default() {
        return 0;
      },
    },
    // 第几组表单
    which: {
      type: [Number, String],
      default() {
        return 1;
      },
    },
    // 是否自定义配置项
    isCustomData: {
      type: Boolean,
      default() {
        return true;
      },
    },
    // 表单数据
    customData: {
      type: Array,
      default() {
        return [];
      },
    },
    // label宽度
    formLabelWidth: {
      type: String,
      default() {
        return "140px";
      },
    },
    //表单配置数据
    formConfigData: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    return {
      formData: [],
      formVal: {}, //表单里的值
      formRules: {},
    };
  },
  computed: {},
  watch: {},
  created() {
    this.getData();
  },
  mounted() {},
  methods: {
    getData() {
      if (this.isCustomData) {
        this.initFormData(this.customData);
      } else {
        let params = {};
        getFormData(params).then((res) => {
          this.initFormData(res.data);
        });
      }
    },
    initFormData(data) {
      //重置表单数据项数据
      if (XEUtils.isArray(data)) {
        let obj = formAdapter.adapterForms(data, this.formConfigData);
        this.formData = obj.formListData;
        this.formRules = obj.formRules;
      }
    },
    //设置表单项数据
    setFormOptions(formData) {
      formData &&
        formData.length &&
        formData.map((item, index) => {
          this.$set(this.formData, index, item);
        });
    },
    //赋值所有表单数据
    setFormValue(formValObj) {
      this.formVal =
        formValObj && XEUtils.isPlainObject(formValObj) ? formValObj : {};
    },
    //赋给单个form值
    setFormSelfValue(codeName, value) {
      this.$set(this.formVal, codeName, value);
    },
    //获取某个数据项的值
    getFormColVal(codeName) {
      codeName = codeName || "";
      let formValue = this.formVal;
      let value = "";
      Object.keys(formValue).map((key) => {
        if (key == codeName) {
          value = formValue[codeName];
        }
      });
      return value;
    },
    //获取表单所有数据项的值
    getFormValueData() {
      return this.formVal;
    },
    //根据数据项编码获取单个数据项数据
    getFormColDataByCode(codeName) {
      codeName = codeName || "";
      let formColData = this.formData ? this.formData : [];
      let formColObj = {};
      formColData.forEach((item, index) => {
        if (item.code == codeName) {
          formColObj = item;
        }
      });
      return formColObj;
    },
    //禁用/启用表单所有数据项 true:启用；false：禁用
    disableOrEnableFormColData(isDisabled) {
      let formColData = this.formData ? this.formData : [];
      formColData.forEach((item, index) => {
        item.isDisabled = isDisabled;
      });
    },
    loadFormLabelWidth(selfWidth) {
      let labeiWidth = selfWidth || this.formLabelWidth;
      labeiWidth = XEUtils.toNumber(labeiWidth) / 16;
      return labeiWidth + "em";
    },
  },
};
</script>
<style lang="less">
.vueFormValidBox {
  .el-form-item {
    margin-bottom: 22px !important;
  }
}
.vueFormBox {
  .el-form-item {
    margin-bottom: 12px;
    .el-radio,
    .el-checkbox {
      line-height: 36px;
    }
  }
  .el-form {
    pre {
      font-family: inherit;
      white-space: normal;
    }
    .el-row {
      .el-form-item {
        .el-form-item__label {
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
      }
    }
    .el-form-item--medium .el-form-item__content {
      line-height: normal;
    }
  }
}
</style>
